/**
 * 公司：广寒宫
 * 网址：www.guanghangong.xyz
 */
package org.moon.framework.autoconfigure.utils;

import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.*;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import org.moon.framework.autoconfigure.exception.domain.MoonException;
import org.moon.framework.autoconfigure.springmvc.response.R;
import sun.reflect.generics.reflectiveObjects.ParameterizedTypeImpl;

import java.io.IOException;
import java.lang.reflect.Type;
import java.util.List;
import java.util.TimeZone;

/**
 * json工具类
 * @author ninglong
 */
@SuppressWarnings("restriction")
public class JsonUtils {

    private static ObjectMapper objectMapper;
    
    static {
        objectMapper = new ObjectMapper();
        objectMapper.setDefaultPropertyInclusion(JsonInclude.Include.NON_NULL);
        objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
        objectMapper.setTimeZone(TimeZone.getDefault());
        //解决localDateTime序列化问题
        objectMapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
        objectMapper.registerModule(new JavaTimeModule());
    }

    /**
     * 将对象转换为json字符串
     */
    public static <T> String obj2string(T t) {
        try {
            return objectMapper.writeValueAsString(t);
        } catch (IOException e) {
            throw new MoonException(e);
        }
    }

    /**
     * 将字符串转list对象
     */
    public static <T> List<T> str2list(String jsonStr, Class<T> cls) {
        try {
            JavaType t = objectMapper.getTypeFactory().constructParametricType(List.class, cls);
            return objectMapper.readValue(jsonStr, t);
        } catch (Exception e) {
            throw new MoonException(e);
        }
    }

    @SuppressWarnings("unchecked")
	public static <T> T str2obj(String jsonStr, TypeReference<?> typeReference) {
        try {
            return (T) objectMapper.readValue(jsonStr, typeReference);
        } catch (IOException e) {
            throw new MoonException(e);
        }
    }


    /**
     * 将字符串转为对象
     */
    public static <T> T str2obj(String jsonStr, Class<T> cls) {
        try {
            return objectMapper.readValue(jsonStr, cls);
        } catch (Exception e) {
            throw new MoonException(e);
        }
    }



    /**
     * 将字符串转为json节点
     */
    public static JsonNode str2node(String jsonStr) {
        try {
            return objectMapper.readTree(jsonStr);
        } catch (Exception e) {
            throw new MoonException(e);
        }
    }

    public static <T> T readAs(byte[] bytes, TypeReference<T> typeReference) {
        try {
            return objectMapper.readValue(bytes, typeReference);
        } catch (IOException e) {
            throw new MoonException(e);
        }
    }

    /**
     * 获取BasicResult中的泛型，传入的是泛型类型
     */
    public static <T> TypeReference<R<T>> getReference(Class<T> clz) {
        Type[] types = new Type[1];
        types[0] = clz;
        final ParameterizedTypeImpl type =
                ParameterizedTypeImpl.make(R.class, types, R.class.getDeclaringClass());
        return new TypeReference<R<T>>() {
            @Override
            public Type getType() {
                return type;
            }
        };
    }
}